package com.ruoyi.ams.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;

import com.ruoyi.ams.domain.vo.*;
import com.ruoyi.ams.service.AmsReusingService;
import com.ruoyi.ams.service.IAmsOwnAddressService;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import com.ruoyi.ams.service.IAssetInfoViewService;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.AssetInfoView;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.domain.vo.AssetInfoVo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.security.service.TokensService;
import com.ruoyi.system.controller.SysDeptController;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * 资产所有方区域信息Controller
 *
 * @author yfkj
 * @date 2021-10-15
 */
@RestController
@RequestMapping("/ams/AmsOwnAddress")
public class AmsOwnAddressController extends BaseController {
    @Autowired
    private IAmsOwnAddressService amsOwnAddressService;
    @Autowired
    private IAssetInfoViewService assetInfoViewService;
    @Autowired
    private IAsmsAssetFullInfoService assetFullInfoService;
    @Autowired
    private AmsReusingService amsReusingService;

    @Autowired
    private TokensService tokenService;

    @Autowired
    private SysDeptController deptController;

    /**
     * 查询资产所有方区域信息列表(树结构)
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:list")
    @GetMapping("/list")
    @ApiOperation("查询资产所有方区域信息列表(树结构)")
    public TableDataInfo list(AmsOwnAddress amsOwnAddress) {
        startPage();
        List<AmsOwnAddress> list = amsOwnAddressService.selectAmsOwnAddressList(amsOwnAddress);
        List<AmsOwnAddress> treeList = amsOwnAddressService.buildTree(list);
        return getDataTable(treeList);
    }

    @GetMapping("/getAddressList")
    public R<List<AmsOwnAddress>> getAddressList() {
        return R.ok(amsOwnAddressService.list());
    }

    /**
     * 查询下拉树表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetType:list")
    @GetMapping("/treeselect")
    @ApiOperation("查询区域下拉框")
    public AjaxResult treeselect(AddressSearchVo addressSearchVo) {
        QueryWrapper<AmsOwnAddress> queryWrapper = new QueryWrapper<>();
        if (addressSearchVo.getDeptId() != null) {
            queryWrapper.eq(AmsOwnAddress.DEPT_ID, addressSearchVo.getDeptId());
        }
        if (addressSearchVo.getParentId() != null) {
            queryWrapper.eq(AmsOwnAddress.PARENT_ID, addressSearchVo.getParentId());
        }
        if (StringUtils.isNotEmpty(addressSearchVo.getFullName())) {
            queryWrapper.eq(AmsOwnAddress.FULL_NAME, addressSearchVo.getFullName());
        }
        if (StringUtils.isNotEmpty(addressSearchVo.getName())) {
            queryWrapper.eq(AmsOwnAddress.NAME, addressSearchVo.getName());
        }
        queryWrapper.orderByDesc(AmsOwnAddress.CREATE_TIME);
        //系统管理员查看所有资产区域、其他用户查看自己可见部门的区域
        Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
        if (!SysUser.isAdmin(SecurityUtils.getUserId()) && userOwnDeptIds != null && userOwnDeptIds.size() > 0) {
            queryWrapper.in(AmsOwnAddress.DEPT_ID, userOwnDeptIds);
        }
        //amsOwnAddressService.buildTreeSelect(amsOwnAddressService.list(queryWrapper));
        return AjaxResult.success(amsOwnAddressService.buildTreeSelect(amsOwnAddressService.list(queryWrapper)));
    }

    /**
     * 查询下拉树表，小程序使用
     */
    @PreAuthorize
    @GetMapping("/treeSelectForMiniApp")
    @ApiOperation("查询区域下拉框，小程序使用")
    public AjaxResult treeSelectForMiniApp(@RequestParam(value = "deptId", required = false) Long deptId) {
        QueryWrapper<AmsOwnAddress> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc(AmsOwnAddress.CREATE_TIME);
        //系统管理员查看所有资产区域、其他用户查看自己可见部门的区域
        if (deptId != null) {
            wrapper.eq(AmsOwnAddress.DEPT_ID, deptId);
        } else {
            Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
            if (!SysUser.isAdmin(SecurityUtils.getUserId()) &&
                    userOwnDeptIds != null && userOwnDeptIds.size() > 0) {
                wrapper.in(AmsOwnAddress.DEPT_ID, userOwnDeptIds);
            }
        }
        List<WxTreeSelect> treeSelects = amsOwnAddressService.buildWxTreeSelect(amsOwnAddressService.list(wrapper));
        return AjaxResult.success(treeSelects);
    }

    /**
     * 导出资产所有方区域信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:export")
    @Log(title = "资产所有方区域信息", businessType = BusinessType.EXPORT)
    @PostMapping(value="/export", produces = "application/octet-stream")
    @ApiOperation("导出资产所有方区域信息列表")
    public void export(HttpServletResponse response, AmsOwnAddress amsOwnAddress) throws IOException {
        List<AmsOwnAddress> list = amsOwnAddressService.selectAmsOwnAddressList(amsOwnAddress);
        ExcelUtil<AmsOwnAddress> util = new ExcelUtil<AmsOwnAddress>(AmsOwnAddress.class);
        util.exportExcel(response, list, "资产所有方区域信息数据");
    }

    /**
     * 获取资产所有方区域信息详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:query")
    @GetMapping(value = "/{addressId}")
    @ApiOperation("获取资产所有方区域信息详细信息,addressId-区域信息ID-Long-必填")
    public AjaxResult getInfo(@PathVariable("addressId") Long addressId) {
        return AjaxResult.success(amsOwnAddressService.selectAmsOwnAddressByAddressId(addressId));
    }

  //  @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:query")
    //@GetMapping(value = "/{addressId}")
    @ApiOperation("获取资产所有方区域信息详细信息,addressId-区域信息ID-Long-必填")
    public R<AmsOwnAddress> getInfoR(Long addressId) {
        return R.ok(amsOwnAddressService.selectAmsOwnAddressByAddressId(addressId));
    }

    /**
     * 新增资产所有方区域信息(同级)
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:add")
    @Log(title = "资产所有方区域信息", businessType = BusinessType.INSERT)
    @PostMapping("/addSibling")
    @ApiOperation("新增资产所有方区域信息(同级)")
    public AjaxResult addSibling(@RequestBody OwnAddressAddVo vo) {
        AmsOwnAddress ownAddress = amsOwnAddressService.getOne(new QueryWrapper<AmsOwnAddress>()
                .eq(AmsOwnAddress.NAME, vo.getName()), false);
        if (ownAddress != null) {
            return AjaxResult.error("位置名称：" + vo.getName() + "已存在!");
        }
        AmsOwnAddress amsOwnAddress = new AmsOwnAddress();
        BeanUtils.copyProperties(vo, amsOwnAddress);
        AmsOwnAddress address = amsOwnAddressService.selectAmsOwnAddressByAddressId(vo.getAddressId());
        if (address != null) {
            amsOwnAddress.setParentId(address.getParentId());
            amsOwnAddress.setAncestors(address.getAncestors());
            AmsOwnAddress addressParent = amsOwnAddressService.selectAmsOwnAddressByAddressId(address.getParentId());
            if (addressParent != null) {
                amsOwnAddress.setFullName(addressParent.getFullName() + vo.getName());
            } else {
                amsOwnAddress.setFullName(vo.getName());
            }
        } else {
            //新增第一个区域信息时
            amsOwnAddress.setParentId(0L);
            amsOwnAddress.setAncestors("0");
            amsOwnAddress.setFullName(vo.getName());
        }
        amsOwnAddress.setCreateBy(SecurityUtils.getUsername());
        return toAjax(amsOwnAddressService.insertAmsOwnAddress(amsOwnAddress));
    }

    /**
     * 新增资产所有方区域信息(下级)
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:add")
    @Log(title = "资产所有方区域信息", businessType = BusinessType.INSERT)
    @PostMapping("/addLower")
    @ApiOperation("新增资产所有方区域信息(下级)")
    public AjaxResult addLower(@RequestBody OwnAddressAddVo vo) {
        AmsOwnAddress amsOwnAddress = new AmsOwnAddress();
        BeanUtils.copyProperties(vo, amsOwnAddress);
        AmsOwnAddress addressParent = amsOwnAddressService.selectAmsOwnAddressByAddressId(vo.getParentId());
        amsOwnAddress.setAncestors(addressParent.getAncestors() + "," + vo.getParentId());
        amsOwnAddress.setFullName(addressParent.getFullName() + vo.getName());
        amsOwnAddress.setCreateBy(SecurityUtils.getUsername());
        return toAjax(amsOwnAddressService.insertAmsOwnAddress(amsOwnAddress));
    }

    /**
     * 修改资产所有方区域信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:edit")
    @Log(title = "资产所有方区域信息", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("修改资产所有方区域信息")
    public AjaxResult edit(@RequestBody OwnAddressEditVo vo) {
        AmsOwnAddress amsOwnAddress = new AmsOwnAddress();
        BeanUtils.copyProperties(vo, amsOwnAddress);
        AmsOwnAddress Address = amsOwnAddressService.getOne(new QueryWrapper<AmsOwnAddress>()
                .eq(AmsOwnAddress.ADDRESS_ID, vo.getParentId()), false);
        if (Address != null) {
            amsOwnAddress.setFullName(Address.getFullName() + vo.getName());
            amsOwnAddress.setAncestors(Address.getAncestors() + "," + vo.getParentId());
        } else {
            amsOwnAddress.setFullName(vo.getName());
        }
        amsOwnAddress.setUpdateBy(SecurityUtils.getUsername());
        amsOwnAddressService.updateAmsOwnAddress(amsOwnAddress);

        //修改资产视图表中的相关数据
        assetFullInfoService.update(new UpdateWrapper<AsmsAssetFullInfo>()
                .set(AsmsAssetFullInfo.ADDRESS_PARENT_ID, vo.getParentId())
                .set(AsmsAssetFullInfo.ADDRESS_ANCESTORS, amsOwnAddress.getAncestors())
                .set(AsmsAssetFullInfo.ADDRESS_NAME, vo.getName())
                .set(AsmsAssetFullInfo.ADDRESS_FULL_NAME, amsOwnAddress.getFullName())
                .set(AsmsAssetFullInfo.LONGITUDE, vo.getLongitude())
                .set(AsmsAssetFullInfo.LATITUDE, vo.getLatitude())
                .eq(AsmsAssetFullInfo.ADDRESS_ID, vo.getAddressId()));
        return AjaxResult.success("修改成功！");
    }

    /**
     * 删除资产所有方区域信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsOwnAddress:remove")
    @Log(title = "资产所有方区域信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{addressId}")
    @ApiOperation("删除资产所有方区域信息,addressId-资产所有方区域信息id-Long-必填")
    public AjaxResult remove(@PathVariable Long addressId) {

        return toAjax(amsOwnAddressService.deleteAmsOwnAddressByAddressId(addressId));
    }

    @GetMapping("/getAddressDeptAssetInfo")
    @ApiOperation("根据地址和部门获取地址及资产信息")
    public R<AddressAssetInfoVo> getAddressDeptAssetInfo(@ApiParam(name = "addressId", value = "地址id", required = true) Long addressId,
                                                         @ApiParam(name = "deptId", value = "部门id", required = true) Long deptId) {
        AddressInfoVo addressInfoVo = new AddressInfoVo();
        AmsOwnAddress address = amsOwnAddressService.getById(addressId);
        BeanUtils.copyProperties(address, addressInfoVo);
        R<SysDept> rDept = deptController.getDeptById(address.getDeptId());
        if(R.FAIL==rDept.getCode()){
            throw new SecurityException(rDept.getMsg());
        }
        addressInfoVo.setFullName(rDept.getData().getDeptShortName()+addressInfoVo.getFullName());
        List<AssetInfoView> assetInfoViews = assetInfoViewService.list(new QueryWrapper<AssetInfoView>()
                .eq(AssetInfoView.ADDRESS_ID, addressId).orderByDesc(AssetInfoView.CREATE_TIME));
        List<AssetInfoVo> assetInfoVos = new ArrayList<>();
        for (AssetInfoView assetInfoView : assetInfoViews) {
            AssetInfoVo assetInfoVo = new AssetInfoVo();
            BeanUtils.copyProperties(assetInfoView, assetInfoVo);
            assetInfoVos.add(assetInfoVo);
        }
        AddressAssetInfoVo result = new AddressAssetInfoVo(addressInfoVo, assetInfoVos);
        return R.ok(result);
    }

    @GetMapping("/getAddressByIds")
    public R<Map<Long, AmsOwnAddress>> getAddressByIds(@RequestParam(value = "ids", required = true) Long[] ids) {
        Map<Long, AmsOwnAddress> map = new HashMap<>();
        if (ids == null || ids.length == 0) {
            return R.ok(map);
        }
        List<AmsOwnAddress> list = amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>().in(AmsOwnAddress.ADDRESS_ID, Arrays.asList(ids)));
        Set<Long> deptIds = new HashSet<>();

        for (AmsOwnAddress address: list) {
            deptIds.add(address.getDeptId());
        }
        R<Map<Long, SysDept>> rDept = deptController.getDeptMapByIds(deptIds);
        if(R.FAIL==rDept.getCode()){
            throw new ServiceException(rDept.getMsg());
        }

        for (AmsOwnAddress address : list) {
            String deptShortName = rDept.getData().get(address.getDeptId()).getDeptShortName();
            address.setFullName(deptShortName+address.getFullName());
            map.put(address.getAddressId(), address);
        }
        return R.ok(map);

    }

    @ApiOperation("根据选择的客户数组获取客户的区域树表")
    @GetMapping("/getAddressForSelectByDeptIds")
    public R<List<TreeSelect>> getAddressForSelectByDeptIds(@ApiParam(name = "deptIds", value = "部门主键ida") Long[] deptIds) {
        if (ArrayUtils.isEmpty(deptIds)) {
            return R.fail("请选择客户！");
        }
        List<TreeSelect> treeSelects = amsOwnAddressService.buildTreeSelect(amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>().in(AmsOwnAddress.DEPT_ID, Lists.newArrayList(deptIds))));
        return R.ok(treeSelects);
    }

    @ApiOperation("获取客户的区域树表")
    @GetMapping("/getAddressForSelect")
    public R<List<TreeSelect>> getAddressForSelect(){
        Set<Long> userOwnDeptIds = tokenService.getUserMaintenanceDeptIds();
        Long[] deptIds = new Long[userOwnDeptIds.size()];
        userOwnDeptIds.toArray(deptIds);
        return getAddressForSelectByDeptIds(deptIds);
    }

    @PostMapping("/importAddressInfo")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public R<Map<String, AmsOwnAddress>> importAddressInfo(@RequestBody DoImportAddressInfoVo vo, @RequestParam("xid")String xid){

        Map<String, AmsOwnAddress> resultMap = new HashMap<>();
        Map<String, Object> map = vo.getDeptMap();
        List<ImportAddressVo> addressVos = vo.getAddressVos();

        for (ImportAddressVo addressVo : addressVos) {
            SysDept dept = JSONObject.parseObject(JSONObject.toJSONString(map.get(addressVo.getUDeptShortName())), SysDept.class);
            if (StringUtils.isNotEmpty(addressVo.getAddressNameNo1())) {
                String ancestors = "0";
                AmsOwnAddress address1 = getOrCreateOwnAddress(addressVo, dept.getDeptId(), 0L, ancestors, resultMap,addressVo.getAddressNameNo1(),addressVo.getAddressNameNo1());
                if (StringUtils.isNotEmpty(addressVo.getAddressNameNo2())) {
                    ancestors = ancestors + "," + address1.getAddressId();
                    AmsOwnAddress address2 = getOrCreateOwnAddress(addressVo, dept.getDeptId(), address1.getAddressId(), ancestors, resultMap,addressVo.getAddressNameNo2(),addressVo.getAddressNameNo2Full());
                    if (StringUtils.isNotEmpty(addressVo.getAddressNameNo3())) {
                        ancestors = ancestors + "," + address2.getAddressId();
                        AmsOwnAddress address3 = getOrCreateOwnAddress(addressVo, dept.getDeptId(), address2.getAddressId(), ancestors, resultMap,addressVo.getAddressNameNo3(),addressVo.getAddressNameNo3Full());
                        if (StringUtils.isNotEmpty(addressVo.getAddressNameNo4())) {
                            ancestors = ancestors + "," + address3.getAddressId();
                            AmsOwnAddress address4 = getOrCreateOwnAddress(addressVo, dept.getDeptId(), address3.getAddressId(), ancestors, resultMap,addressVo.getAddressNameNo4(),addressVo.getAddressNameNo4Full());
                            if (StringUtils.isNotEmpty(addressVo.getAddressNameNo5())) {
                                ancestors = ancestors + "," + address4.getAddressId();
                                AmsOwnAddress address5 = getOrCreateOwnAddress(addressVo, dept.getDeptId(), address4.getAddressId(), ancestors, resultMap,addressVo.getAddressNameNo5(),addressVo.getFullAddress());
                            }
                        }
                    }
                }
            }
        }
        return R.ok(resultMap);
    }


    @Transactional
    public AmsOwnAddress getOrCreateOwnAddress(ImportAddressVo addressVo, Long deptId, long parentId, String ancestors, Map<String, AmsOwnAddress> resultMap, String name, String fullName) {

        AmsOwnAddress address = new AmsOwnAddress();
        BeanUtils.copyProperties(addressVo, address);
        address.setName(name);
        address.setFullName(fullName);
        address.setDeptId(deptId);
        address.setAncestors(ancestors);
        address.setParentId(parentId);
        address = amsReusingService.getOrCreateOwnAddressByNameAndParentIdAndDeptId(address);
        resultMap.put(address.getFullName(), address);
        return address;

    }

    @PreAuthorize
    @ApiOperation("根据部门Id获取资产地址树结构")
    @GetMapping("/getAddressesTreeSelectByDeptId")
    public AjaxResult getAddressesTreeSelectByDeptId(@RequestParam("deptId") Long deptId) {
        List<AmsOwnAddress> addressList = amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>()
                .eq(AmsOwnAddress.DEPT_ID, deptId));
        List<WxTreeSelect> treeSelect = amsOwnAddressService.buildWxTreeSelect(addressList);
        return AjaxResult.success(treeSelect);
    }

    @ApiOperation("新增地址")
    @PostMapping("/addAddress")
    public R<Map<String, AmsOwnAddress>> addAddress(@RequestBody List<AmsOwnAddress> addressList) {

     //   List<AmsOwnAddress> addTem = new LinkedList<>();

//        for(AmsOwnAddress amsOwnAddress:addressList){
//            List<AmsOwnAddress> list = amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>().eq(AmsOwnAddress.FULL_NAME, amsOwnAddress.getFullName()));
//            if(list == null || list.size() == 0) {
//                addTem.add(amsOwnAddress);
//            }
//
//        }

        amsOwnAddressService.saveBatch(addressList);

        Map<String, AmsOwnAddress> res = new HashMap<>();
        for(AmsOwnAddress amsOwnAddress:addressList){
            res.put(amsOwnAddress.getFullName(),amsOwnAddress);
        }

        return R.ok(res);
    }

}
